package xyz.scootaloo.kami.server.controller

import io.vertx.ext.web.Router
import io.vertx.ext.web.RoutingContext
import xyz.scootaloo.kami.server.controller.dto.SimpleFileDTO
import xyz.scootaloo.kami.server.controller.dto.MoveFileDTO
import xyz.scootaloo.kami.server.controller.dto.RenameFileDTO
import xyz.scootaloo.kami.server.controller.dto.SC
import xyz.scootaloo.kami.server.service.FileResolver
import xyz.scootaloo.kami.server.standard.getLogger
import xyz.scootaloo.kami.server.service.FileSystemViewService
import xyz.scootaloo.kami.server.service.HttpMessageHelper

/**
 * @author flutterdash@qq.com
 * @since 2022/1/9 14:51
 */
object FileViewController : BaseController() {

    private val fileResolver = FileResolver()
    private val viewService = FileSystemViewService()

    override val log by lazy { getLogger() }
    override val enableJwt = true
    override val mountPoint = "/file"

    override fun doRoute(router: Router) = router.apply {
        get("/list") { ctx ->
            val path = ctx.uriParam("path")
            val dirContent = viewService.listDirectoryContent(ctx.access(path))
            ctx.rest(dirContent)
        }

        get("/info") { ctx ->
            val path = ctx.uriParam("path")
            val info = viewService.showFileDesc(ctx.access(path))
            ctx.rest(info)
        }

        get("/cap") { ctx ->
            val path = ctx.uriParam("path")
            val capInfo = viewService.displayDirectoryCap(ctx.access(path))
            ctx.rest(capInfo)
        }

        post("/downloadLink") { ctx ->
            val form = ctx.readBodyAsDTO(SimpleFileDTO::class)
            val filepath = fileResolver.buildFilepath(form.path, form.filename)
            val ipAddress = HttpMessageHelper.getIpAddress(ctx.request())
            val downloadLink = viewService.createFileDownloadLink(ctx.access(filepath), ipAddress)
            ctx.rest(downloadLink)
        }

        post("/rename") { ctx ->
            val form = ctx.readBodyAsDTO(RenameFileDTO::class)
            viewService.renameFile(ctx.access(form.path), form.filename, form.newName)
            ctx.rest()
        }

        post("/move") { ctx ->
            val form = ctx.readBodyAsDTO(MoveFileDTO::class)
            viewService.moveFile(ctx.access(form.path), form.filename, form.dest)
            ctx.rest()
        }

        post("/copy") { ctx->
            ctx.restWithCode(SC.FEATURE_NOT_AVAILABLE)
        }

        post("/delete") { ctx ->
            val form = ctx.readBodyAsDTO(SimpleFileDTO::class)
            viewService.deleteFile(ctx.access(form.path), form.filename)
            ctx.rest()
        }

        post("/createFile") { ctx ->
            val form = ctx.readBodyAsDTO(SimpleFileDTO::class)
            viewService.createFile(ctx.access(form.path), form.filename)
            ctx.rest()
        }

        post("/createDir") { ctx ->
            val form = ctx.readBodyAsDTO(SimpleFileDTO::class)
            viewService.createDirectory(ctx.access(form.path), form.filename)
            ctx.rest()
        }
    }

    private fun RoutingContext.uriParam(param: String, def: String = "/"): String {
        return decodeURIComponent(this.request().getParam(param) ?: def)
    }
}